﻿using GrapeCity.Forguncy.SecurityProvider;

namespace ForguncyTemplateSecurityProvider;

/// <summary>
/// 一个简单的基于 Password 实现的安全提供程序样例
/// </summary>
public class ForguncyTemplateSecurityProvider : ISecurityProvider
{
    /// <summary>
    /// 这是一个模拟出来的数据库
    /// 真是场景中应该是一次数据库请求或者 Api 调用
    /// </summary>
    private readonly Dictionary<string, User> _userDatabase = new();

    /// <summary>
    /// 安全提供程序名称，主要用于在服务器中展示
    /// </summary>
    public string Name => "一个测试安全提供程序的名称";

    /// <summary>
    /// 第三方系统中的所有用户信息，如果不需要提供用户信息，则返回 null
    /// </summary>
    public UserInformations UserInformations => null;

    /// <summary>
    /// 用户认证的类型，目前默认为 UserNameAndPassword 即账号密码认证
    /// 此例中也以这种方式进行认证
    /// </summary>
    public AuthenticationType AuthenticationType => AuthenticationType.UserNameAndPassword;

    /// <summary>
    /// 第三方应用获取的数据如何在活字格中保存，目前默认为 InForguncyDatabase 即保存在活字格数据库中
    /// 此例中也以这种方式进行保存
    /// </summary>
    public UserInformationStorageMode UserInformationStorageMode => UserInformationStorageMode.InForguncyDatabase;

    /// <summary>
    /// 是否支持登出操作，如果支持，则在活字格中可以执行登出操作
    /// </summary>
    public bool AllowLogout { get; }

    /// <summary>
    /// 认证用户，在登录活字格时会调用此方法
    /// </summary>
    /// <param name="properties">所需用户相关信息的参数字典，此例中，用户名以及密码会从此参数中获取</param>
    /// <returns>认证成功则返回用户信息，否则可以返回 null 表示用户认证失败</returns>
    public User VerifyUser(Dictionary<string, string> properties)
    {
        // 验证密码示例，实际上需要根据不同用户验证不同密码
        if (!properties.TryGetValue("password", out var password) || password != "123456")
        {
            // 没有密码或验证失败
            return null;
        }

        // 实现用户认证逻辑（仅用于演示，实际应根据传入的属性进行认证）
        if (properties.TryGetValue("userName", out var userName)
            && _userDatabase.TryGetValue(userName, out var user))
        {
            return user; // 认证成功，返回用户
        }

        return null; // 认证失败，返回空
    }
}